package pl.diagnoser.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.hibernate.Session;
import pl.diagnoser.client.dto.AppDTO;
import pl.diagnoser.client.dto.AttributeDictDTO;
import pl.diagnoser.client.dto.AttributeValuesDictDTO;
import pl.diagnoser.client.dto.DefectDictDTO;
import pl.diagnoser.client.dto.DiagnoserResultDTO;
import pl.diagnoser.client.dto.DiagnoserResultsDTO;
import pl.diagnoser.client.dto.EstimateDTO;
import pl.diagnoser.client.dto.ObjectHistoryViewer;
import pl.diagnoser.client.dto.SearchResultAttributesDTO;
import pl.diagnoser.client.dto.SearchResultDTO;
import pl.diagnoser.client.dto.SymptomDTO;
import pl.diagnoser.client.dto.SymptomDictDTO;
import pl.diagnoser.client.dto.UserDTO;
import pl.diagnoser.client.dto.ObjectAttributesDTO;
import pl.diagnoser.client.dto.ObjectsDTO;
import pl.diagnoser.client.formulas.DiagnoserHBFormula;
import pl.diagnoser.client.formulas.DiagnoserIFormula;
import pl.diagnoser.client.formulas.DiagnoserSFormula;
import pl.diagnoser.client.formulas.DiagnoserVFormula;
import pl.diagnoser.client.tools.DataGetterService;
import pl.diagnoser.client.tools.SearchObjectAttribute;
import pl.diagnoser.server.persistance.dao.AppDao;
import pl.diagnoser.server.persistance.dao.AttributeDictDao;
import pl.diagnoser.server.persistance.dao.AttributeValuesDictDao;
import pl.diagnoser.server.persistance.dao.DefectDictDao;
import pl.diagnoser.server.persistance.dao.DiagnoserDao;
import pl.diagnoser.server.persistance.dao.EstimateDao;
import pl.diagnoser.server.persistance.dao.SearchResultAttributesDao;
import pl.diagnoser.server.persistance.dao.SearchResultDao;
import pl.diagnoser.server.persistance.dao.SymptomDao;
import pl.diagnoser.server.persistance.dao.SymptomDictDao;
import pl.diagnoser.server.persistance.dao.UserDao;
import pl.diagnoser.server.persistance.dao.ObjectAttributesDao;
import pl.diagnoser.server.persistance.dao.ObjectsDao;
import pl.diagnoser.server.persistance.map.App;
import pl.diagnoser.server.persistance.map.Estimate;
import pl.diagnoser.server.persistance.map.Objects;
import pl.diagnoser.server.persistance.map.Symptom;
import pl.diagnoser.server.persistance.tools.HibernateUtil;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class DataGetterServiceImpl extends RemoteServiceServlet implements
		DataGetterService {

	private static final long serialVersionUID = 1L;
    
    public List<ObjectsDTO> getListOfAllObjects() {
    	return new ObjectsDao().getListOfAllObjects();
    }
    
    public Long saveNewObject(String objectName, String objectDate, HashMap<String, String> objectAttributes, HashMap<String, List<String>> objectMultipleAttributes) {
    	return new ObjectsDao().saveNewObject(objectName, objectDate, objectAttributes, objectMultipleAttributes);
    }
    
	public List<AttributeDictDTO> getAttributeList(boolean loadValues) {
		return new AttributeDictDao().getAttributeList(loadValues);
	}
	
	public List<AttributeValuesDictDTO> getAttributeValuesList() {
		return new AttributeValuesDictDao().getAttributeValuesList();
	}
    
    public String getWebPageForArticle(String article) {
    	String path = this.getServletContext().getRealPath("articleWebPage.properties");
    	Properties prop = new Properties();
    	try {
			prop.load(new FileInputStream(path));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    	
    	return prop.getProperty(article);
    }
    
    public String getWidgetTitle(String widgetName) {
    	App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + ".properties");
    	
    	//String path = this.getServletContext().getRealPath("objectNames.properties");
    	Properties prop = new Properties();
    	try {
			prop.load(new FileInputStream(path));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    	
    	return prop.getProperty(widgetName, widgetName);
    }
    
    public List<DiagnoserResultsDTO> getLearnResult(Integer mode, Double slider) {
    	App app = new AppDao().getActiveApp();
    	String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
    	return new DiagnoserDao().getLearnResult(mode, slider, path);
    }
	
	public String saveAttribute(String attribute, int isDate, int isMultiple, int isFile) {
		return new AttributeDictDao().saveAttribute(attribute, isDate, isMultiple, isFile);
	}
	
	public String saveAttributeValue(String attribute, String attributeValue) {
		return new AttributeValuesDictDao().saveAttributeValue(attribute, attributeValue);
	}
	
	public String removeAttribute(String attribute) {
		return new AttributeDictDao().removeAttribute(attribute);
	}
	
	public String removeAttributeValue(String attribute, String attributeValue) {
		return new AttributeValuesDictDao().removeAttributeValue(attribute, attributeValue);
	}
	
	public List<DiagnoserHBFormula> getHBFormulas() {
		//String path = this.getServletContext().getRealPath("knowledgeBase.txt");
		App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
		String pathOrg = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_ORG.properties");
		if(!new File(pathOrg).exists())
			pathOrg = path;
		return new DiagnoserDao().getHBFormulas(path, pathOrg);
	}
	
	public List<DiagnoserVFormula> getVFormulas() {
		//String path = this.getServletContext().getRealPath("knowledgeBase.txt");
		App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
		String pathOrg = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_ORG.properties");
		if(!new File(pathOrg).exists())
			pathOrg = path;
		return new DiagnoserDao().getVFormulas(path, pathOrg);
	}
	
	public List<DiagnoserSFormula> getSFormulas() {
		//String path = this.getServletContext().getRealPath("knowledgeBase.txt");
		App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
		String pathOrg = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_ORG.properties");
		if(!new File(pathOrg).exists())
			pathOrg = path;
		return new DiagnoserDao().getSFormulas(path, pathOrg);
	}
	
	public List<DiagnoserIFormula> getIFormulas() {
		//String path = this.getServletContext().getRealPath("knowledgeBase.txt");
		App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
		String pathOrg = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_ORG.properties");
		if(!new File(pathOrg).exists())
			pathOrg = path;
		return new DiagnoserDao().getIFormulas(path, pathOrg);
	}
	
	public String saveImplication(List<String> implications) {
		//String path = this.getServletContext().getRealPath("knowledgeBase.txt");
		App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
		return new DiagnoserDao().saveImplication(implications, path);
	}
	
	public Set<ObjectAttributesDTO> getObjectAttributes(Long objectId) {
		return new ObjectAttributesDao().getObjectAttributes(objectId);
	}
	
	public UserDTO getUser(String login, String password) {
		return new UserDao().getUser(login, password);
	}
	
	public List<UserDTO> getUserList() {
		return new UserDao().getUserList();
	}
	
	public String saveUser(UserDTO user) {
		return new UserDao().saveUser(user);
	}
	
	public String removeUser(long userID) {
		return new UserDao().removeUser(userID);
	}
	
	public ArrayList<String> getAttributeValue(String attributeName) {
		return new AttributeDictDao().getAttributeValues(attributeName);
	}
	
	public String saveSearching(List<SearchObjectAttribute> objectAttributes, long objectId) {
		return new SearchResultDao().saveSearching(objectAttributes, objectId);
	}
	
	public List<SearchResultDTO> getSearchResultForObject(long objectId) {
		return new SearchResultDao().getSearchResultForObject(objectId);
	}
	
	public List<SearchResultAttributesDTO> getHistorySearchAttributes(long searchID) {
		return new SearchResultAttributesDao().getHistorySearchAttributes(searchID);
	}
	
	public String openPdfFile(String fileName) {
		String path = getServletContext().getRealPath("articles") + System.getProperty("file.separator");
		return new DiagnoserDao().openPdfFile(fileName, path);
	}

	public List<DiagnoserResultDTO> getPossibleDefects( List<SearchObjectAttribute> searchCriteria, List<SearchObjectAttribute> emptySearchCriteria, boolean fast ) {
    	//String path = this.getServletContext().getRealPath("knowledgeBase.txt");
		App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
    	return new DiagnoserDao().getPossibleDefects(searchCriteria, emptySearchCriteria, path, fast);
    }
	
	public List<DefectDictDTO> getPossibleDefects( ObjectsDTO object, List<SymptomDTO> symptoms ) {
    	App app = new AppDao().getActiveApp();
		String path = this.getServletContext().getRealPath(app.getAppName().toLowerCase().replace(" ", "_") + "_KB.txt");
		return new DiagnoserDao().getPossibleDefects(object, symptoms, path);
    }
	
	////////
	public List<ObjectHistoryViewer> getEstimateForObject(Long id) {
        return new EstimateDao().getEstimateForObjects(id);
    }
	
	public List<SymptomDictDTO> getSymptomsList() {
		return new SymptomDictDao().getSymptomsList();
	}
	
	public List<DefectDictDTO> getDefectsList() {
		return new DefectDictDao().getDefectsList();
	}
	
	public String saveDefect(String newValue) {
        return new DefectDictDao().saveDefect(newValue);
	}

	public String saveSymptom(String newValue) {
        return new SymptomDictDao().saveSymptom(newValue);
	}

	public String removeDefects(List<String> defects) {
        return new DefectDictDao().removeDefects(defects);
	}

	public String removeSymptoms(List<String> symptoms) {
        return new SymptomDictDao().removeSymptoms(symptoms);
	}
	
	public Boolean saveNewEstimate(EstimateDTO estimateDTO, List<SymptomDTO> symptoms) {
        Session session = HibernateUtil.getSessionFactory().openSession();
                session.beginTransaction();
                
        Estimate estimate = new Estimate(estimateDTO);
                estimate.setEstimateObject(new Objects(estimateDTO.getObjects()));
        Long estimateID = new EstimateDao().saveEstimate(estimate, session);
        
        if(estimateID != null && estimateID >= 0) {
                for(SymptomDTO symptomDTO : symptoms) {
                        Symptom symptom = new Symptom(symptomDTO, estimate);
                        Long symptomID = new SymptomDao().saveSymptom(symptom, session);
                        if(symptomID == null || symptomID <= 0) 
                                return false;
                }
        }
        else
                return false;
        
        session.getTransaction().commit();
                session.close();
        return true;
    }
	
	public List<AppDTO> getAllApp() {
		return new AppDao().getAllApp();
	}
	
	public String updateApp(Long appID, int isActive, String appName, int isSearchMode) {
		return new AppDao().updateApp(appID, isActive, appName, isSearchMode);
	}
	
	public String removeApp(String appName) {
		return new AppDao().removeApp(appName);
	}
	
	public String getHibernateConfig() {
		return this.getServletContext().getRealPath("hibernate.cfg.xml");
	}
}
